/*
 * File: RightSideBarModel.cs
 * Author: Gourav Das
 * Purpose: Model for PhotoFrames
 * Created: May 21 2011
 */

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;


namespace _22yards.ThreeD
{
    /// <summary>
    /// This is a game component that implements CustomModel.
    /// </summary>
    public class RightSideBarModel : CustomModel
    {
        private int oscDir; //0 No Osc, 1 right Osc, 2 left Osc
        private float angle = 0;
        private float angle1 = 0;
        private float angle2 = 0;
        private float oscSpeed = 0.05f;

        /// <summary>
        /// Gets or sets the oscillation speed.
        /// </summary>
        /// <value>
        /// The oscillation speed.
        /// </value>
        public float OscillationSpeed
        {
            get
            {
                return oscSpeed;
            }
            set
            {
                oscSpeed = value;
            }
        }

        /// <summary>
        /// Resets the oscillation speed.
        /// </summary>
        public void ResetOscillationSpeed()
        {
            oscSpeed = 0.02f;
        }

        List<Vector3> animpos = new List<Vector3>();
        List<Vector3> animrot = new List<Vector3>();

        int i = 0;

        /// <summary>
        /// If transitioning out mode
        /// </summary>
        public bool transitionOut = false;
        /// <summary>
        /// If transitioing in mode
        /// </summary>
        public bool transitionIn = false;

        /// <summary>
        /// Gets the osc dir. 0 - No Oscillations, 1 - left, 2 - right
        /// </summary>
        public int OscDir
        {
            get
            {
                return oscDir;
            }
        }

        /// <summary>
        /// Gets the angle of oscillations
        /// </summary>
        public float Angle
        {
            get
            {
                return angle;
            }
        }

        private bool oscillate = true;
        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="PhotoFrameModel"/> will oscillate.
        /// </summary>
        /// <value>
        ///   <c>true</c> if oscillate; otherwise, <c>false</c>.
        /// </value>
        public bool Oscillate
        {
            get
            {
                return oscillate;
            }
            set
            {
                oscillate = value;
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="RightSideBarModel"/> class.
        /// </summary>
        /// <param name="_Model">The _ model.</param>
        /// <param name="_Position">The _ position.</param>
        /// <param name="_Rotation">The _ rotation.</param>
        /// <param name="_Scale">The _ scale.</param>
        /// <param name="_graphicsDevice">The _graphics device.</param>
        /// <param name="_Name">Name of the _.</param>
        /// <param name="_ID">The _ ID.</param>
        /// <param name="Oscillate">The oscillate.</param>
        public RightSideBarModel(Model _Model, Vector3 _Position, Vector3 _Rotation,
            Vector3 _Scale, GraphicsDevice _graphicsDevice, string _Name, short _ID, int Oscillate)
            : base(_Model,
                _Position, _Rotation, _Scale, ref _graphicsDevice, _Name, _ID)
        {
            oscDir = Oscillate;
            angle = (oscDir == 1) ? 0 : 360;
        }

        private void OscillatePhotoFrame()
        {
            Rotation = new Vector3(0, (float)Math.Sin(MathHelper.ToRadians(angle)) * oscSpeed, 0);
            if (oscDir == 1)
            {
                if (angle > 360f)
                {
                    angle = 0;
                }
                else
                {
                    angle += 0.5f;
                }
            }
            else
            {
                if (angle < 0f)
                    angle = 360f;
                else
                    angle -= 0.5f;
            }
        }

        /// <summary>
        /// Syncs the oscillations with another model.
        /// </summary>
        /// <param name="_model">The _model.</param>
        public void SyncOscillationsWithModel(PhotoFrameModel _model)
        {
            oscDir = _model.OscDir;
            angle = _model.Angle;
        }


        void TransitionModelOut()
        {
            animrot.Add(Rotation);
            animpos.Add(Position);

            if (MathHelper.ToRadians(angle1) + 0.05f <= (MathHelper.Pi))
            {
                angle1 += (MathHelper.Pi - MathHelper.ToRadians(angle1)) * 1.8f;

                Position += new Vector3(-(float)Math.Sin(MathHelper.ToRadians(angle1 * 1.5f)) - 0.2f, 0f, 1.5f);
                Rotation = new Vector3(0+Rotation.X, MathHelper.ToRadians(angle1), 0+Rotation.Z);

            }

            if (MathHelper.ToRadians(angle2) + 0.33f > MathHelper.TwoPi)
            {
                transitionOut = false;
                angle1 = 0f;
                angle2 = 0f;
            }
            else
            {
                angle2 += (MathHelper.TwoPi - MathHelper.ToRadians(angle2)) * 2.7f;
                Rotation = new Vector3(MathHelper.ToRadians(angle2), 0+Rotation.Y, 0+Rotation.Z);
            }

        }

        void TransitionModelIn()
        {
            if (i < animrot.Count)
            {
                Position = animpos[animpos.Count - 1 - i];

                Rotation = animrot[animrot.Count - 1 - i];
                i++;
            }
            else
            {
                transitionIn = false;
                transitionOut = false;
                animpos.Clear();
                animrot.Clear();
                i = 0;
            }

        }


        /// <summary>
        /// Updates this instance.
        /// </summary>
        public override void Update()
        {
            if (transitionIn)
                TransitionModelIn();

            if (transitionOut)
            {
                TransitionModelOut();
            }

            if (oscDir > 0 && oscillate && !transitionOut && !transitionIn)
                OscillatePhotoFrame();

            base.Update();
        }
    }

}
